package org.example.batch;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

/**
 * 简单的 Tasklet 实现 - 教学版本
 * 
 * Tasklet 是 Spring Batch 中最简单的处理模式，适用于：
 * 1. 不需要复杂读取-处理-写入流程的任务
 * 2. 一次性执行的任务（如系统初始化、数据清理等）
 * 3. 调用存储过程或执行单一操作
 * 4. 文件操作（如文件移动、压缩等）
 * 
 * Tasklet vs Chunk 模式：
 * - Tasklet：适合简单任务，一次性处理
 * - Chunk：适合大量数据处理，分批处理
 * 
 * @author example
 */
public class SimpleTasklet implements Tasklet {

    /**
     * 执行具体的任务逻辑
     * 
     * @param contribution Step贡献对象，包含当前Step的执行统计信息
     *                    - readCount: 读取记录数
     *                    - writeCount: 写入记录数
     *                    - filterCount: 过滤记录数
     *                    - readSkipCount: 读取跳过记录数
     *                    - writeSkipCount: 写入跳过记录数
     *                    - processSkipCount: 处理跳过记录数
     * 
     * @param chunkContext 块上下文，提供Step和Job的上下文信息
     *                    - stepContext: Step上下文，可以获取Step名称、参数等
     *                    - stepExecution: Step执行对象，包含执行状态、时间等
     *                    - jobParameters: Job参数，可以获取启动Job时传入的参数
     * 
     * @return RepeatStatus 返回状态
     *         - FINISHED: 任务完成，不再重复执行
     *         - CONTINUABLE: 任务未完成，需要继续执行（很少使用）
     * 
     * @throws Exception 如果处理过程中发生异常
     */
    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        System.out.println("=== Spring Batch Tasklet 任务开始执行 ===");
        System.out.println("当前时间: " + new java.util.Date());
        
        // 获取Job参数示例（如果启动时传入了参数）
        String jobName = chunkContext.getStepContext().getJobName();
        String stepName = chunkContext.getStepContext().getStepName();
        System.out.println("所属Job: " + jobName);
        System.out.println("当前Step: " + stepName);
        
        // 获取Job参数（如果需要的话）
        Object timestamp = chunkContext.getStepContext().getJobParameters().get("time");
        if (timestamp != null) {
            System.out.println("Job启动时间戳: " + timestamp);
        }
        
        // 模拟实际的业务处理工作
        // 在实际应用中，这里可能是：
        // - 调用存储过程
        // - 执行数据清理工作
        // - 文件处理操作
        // - 系统初始化任务
        // - 发送通知邮件
        // - 生成报告等
        
        for (int i = 1; i <= 5; i++) {
            System.out.println("正在处理第 " + i + " 项任务...");
            
            // 模拟处理时间（实际应用中删除这行）
            Thread.sleep(1000);
            
            // 可以通过contribution来更新处理统计
            // 虽然Tasklet通常不需要这样做，但在某些场景下很有用
            contribution.incrementReadCount(); // 假设读取了一条记录
            contribution.incrementWriteCount(1); // 假设写入了一条记录
        }
        
        // 任务执行完成后的清理工作
        System.out.println("任务处理完成，共处理了 5 项任务");
        System.out.println("Step统计信息:");
        System.out.println("  - 读取记录数: " + contribution.getReadCount());
        System.out.println("  - 写入记录数: " + contribution.getWriteCount());
        
        System.out.println("=== Spring Batch Tasklet 任务执行完成 ===");
        
        // 返回 FINISHED 表示任务完成
        // Spring Batch会根据这个返回值决定是否继续执行
        // 大多数情况下都返回FINISHED
        return RepeatStatus.FINISHED;
    }
} 